package nature.nano.component.part;

import java.util.HashSet;
import java.util.Set;

import nature.nano.component.Strings;
import nature.nano.iface.Pipe;
import nature.nano.iface.Props;

public abstract class GammaNode extends AlphaNode implements Pipe {
	
	private boolean initialized = false;
	private Set<String> throughs = new HashSet<String>();
	private boolean allThrough = false;
	
	private static final String illegalInitialize = "illegal initialize when stream launched, you should call this method in initialize()";
	
	@Override
	public final void onBegin(String type, Props props) {
		if (!initialized) {
			initialize();
			initialized = true;
		}
		if (allThrough || throughs.contains(type)) {
			error().onBegin(type, props);
			output().onBegin(type, props);
		}
		anBegin(type, props);
	}

	@Override
	public final void onContent(String content) {
		anContent(content);
	}

	@Override
	public final void onEnd(String type) {
		if (allThrough || throughs.contains(type)) {
			error().onEnd(type);
			output().onEnd(type);
		}
		anEnd(type);
	}

	protected void through(String... types) {
		if (initialized) {
			error(Strings.error, Strings.errorType, illegalInitialize, Strings.method, "through");
			return;
		}
		for (String type : types) {
			throughs.add(type);
		}
	}
	
	protected void allThrough() {
		if (initialized) {
			error(Strings.error, Strings.errorType, illegalInitialize, Strings.method, "through");
			return;
		}
		allThrough  = true;
	}
	
	protected abstract void initialize();
	
	protected abstract void anBegin(String type, Props props);

	protected abstract void anContent(String content);
	
	protected abstract void anEnd(String type);
	
}
